package main

import (
	// "github.com/fsnotify/fsnotify"
	"crypto/rand"
	"database/sql"
	"fmt"
	"io"
	"log"
	"os"
	"path"
	"strconv"
	"strings"
	"time"

	"gitee.com/kkstun/go-fsnotify"
	_ "github.com/lib/pq"
)

const (
	host     = "localhost"
	port     = 5432
	user     = "admin"
	password = "admin"
	dbname   = "testdb"
)

func main() {
	//创建一个监控对象
	watch, err := fsnotify.NewWatcher()
	if err != nil {
		log.Fatal(err)
	}
	defer watch.Close()
	//添加要监控的对象，文件或文件夹

	//连接数据库
	psqlInfo := fmt.Sprintf("host=%s port=%d user=%s "+
		"password=%s dbname=%s sslmode=disable",
		host, port, user, password, dbname)
	db, err := sql.Open("postgres", psqlInfo)
	if err != nil {
		panic(err)
	}
	defer db.Close()

	sendfilespath := "/root/sendfiles"
	mvfilespath := "/root/files"
	err = watch.Add(sendfilespath)
	log.Println("开始监控文件夹：" + sendfilespath)
	//	filespath := "/root/files"
	if err != nil {
		log.Panicln(err)
	}
	//我们另启一个goroutine来处理监控对象的事件
	go func() {
		for {
			select {
			case ev := <-watch.Events:
				{
					if ev.Op&fsnotify.Update == fsnotify.Update {
						log.Println("新文件 : ", ev.Name)

						filenameonly, filetype, origin_filesize, origin_filetime := GetFile(ev.Name)

						log.Println("文件大小：" + origin_filesize)
						log.Println("文件时间：" + origin_filetime)
						log.Println("文件后缀名：" + filetype)
						full_filename := mvfilespath + "/" + filetype + "/" + filenameonly + "_" + time.Now().Format("150405") + "_" + NewLenChars(6) + "." + filetype
						Mvfile(ev.Name, full_filename)
					}

				}
			case err := <-watch.Errors:
				{
					log.Println("error : ", err)
					return
				}
			}
		}
	}()

	//使用select{}阻塞main函数
	select {}
}

func GetFile(filename string) (string, string, string, string) {
	//文件大小
	fileSuffix := path.Ext(filename)                                   //获取文件后缀
	filenameWithSuffix := path.Base(filename)                          //获取文件名带后缀
	filenameOnly := strings.TrimSuffix(filenameWithSuffix, fileSuffix) //获取文件名
	fileSuffix = strings.Replace(fileSuffix, ".", "", -1)
	fileInfo, _ := os.Stat(filename)
	filesize := fileInfo.Size()    //返回的是字节
	filetime := fileInfo.ModTime() //返回的是文件修改时间
	return filenameOnly, fileSuffix, strconv.FormatInt(filesize, 10), filetime.Format("2006-01-02 15:04:05")
	/*
		#string到int
		int,err:=strconv.Atoi(string)
		#string到int64
		int64, err := strconv.ParseInt(string, 10, 64)
		#int到string
		string:=strconv.Itoa(int)
		#int64到string
		string:=strconv.FormatInt(int64,10)
	*/

}

func Mvfile(src, des string) {
	_, err := CopyFile(src, des)
	if err != nil {
		log.Println(err.Error())
	} else {
		err = Delfile(src)
		if err != nil {
			log.Println(err.Error())
		} else {
			log.Println("文件转移成功")
		}
	}
}

func Delfile(filename string) (err error) {
	//	err = os.Remove(filename) //删除文件
	//	if err != nil {
	//		//如果删除失败则输出 file remove Error!
	//		log.Println("文件移除错误!")
	//		//输出错误详细信息
	//		log.Println("%s", err)
	//	} else {
	//		//如果删除成功则输出 file remove OK!
	//		//		log.Println("文件移除成功!")
	//	}
	return os.Remove(filename)
}

func CopyFile(src, des string) (w int64, err error) {
	srcFile, err := os.Open(src)
	if err != nil {
		log.Println(err.Error())
	}
	defer srcFile.Close()

	desFile, err := os.Create(des)
	if err != nil {
		log.Println(err.Error())
	}
	defer desFile.Close()

	return io.Copy(desFile, srcFile)
}

//生成随机数
func NewLenChars(length int) string {
	var chars = []byte("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789")
	if length == 0 {
		return ""
	}
	clen := len(chars)
	if clen < 2 || clen > 256 {
		panic("Wrong charset length for NewLenChars()")
	}
	maxrb := 255 - (256 % clen)
	b := make([]byte, length)
	r := make([]byte, length+(length/4)) // storage for random bytes.
	i := 0
	for {
		if _, err := rand.Read(r); err != nil {
			panic("Error reading random bytes: " + err.Error())
		}
		for _, rb := range r {
			c := int(rb)
			if c > maxrb {
				continue // Skip this number to avoid modulo bias.
			}
			b[i] = chars[c%clen]
			i++
			if i == length {
				return string(b)
			}
		}
	}
}
